#include "Data.hpp"
#include "httplib.h"
#include "Log.hpp"
#include <stdexcept>
#include <memory>

namespace vedio_sharing
{
    // 使用常量替代宏定义，提高安全性和可读性
    const std::string WWWROOT = "./www";
    const std::string VIDEO_ROOT = "/video/";
    const std::string IMAGE_ROOT = "/image/";

    // 使用智能指针管理 TableVideo 对象，避免内存泄漏
    std::unique_ptr<TableVideo> tb_video;

    class Server
    {
    private:
        int _port;
        httplib::Server _srv;

        // 插入视频信息的处理函数
        static void Insert(const httplib::Request &req, httplib::Response &rsp)
        {
            // 检查请求中是否包含必要的文件信息
            if (!req.has_file("name") || !req.has_file("info") || !req.has_file("video") || !req.has_file("image"))
            {
                rsp.status = 400;
                rsp.body = R"({"result":false, "reason":"上传的数据信息错误"})";
                rsp.set_header("Content-Type", "application/json");
                return;
            }

            // 获取请求中的文件信息
            const auto name = req.get_file_value("name");
            const auto info = req.get_file_value("info");
            const auto video = req.get_file_value("video");
            const auto image = req.get_file_value("image");

            // 提取视频名称和简介
            const std::string video_name = name.content;
            const std::string video_info = info.content;

            // 构建视频和图片的存储路径
            const std::string video_path = WWWROOT + VIDEO_ROOT + video_name + video.filename;
            const std::string image_path = WWWROOT + IMAGE_ROOT + video_name + image.filename;

            // 保存视频文件
            if (!FileUtil(video_path).SetContent(video.content))
            {
                rsp.status = 500;
                rsp.body = R"({"result":false, "reason":"视频文件存储失败"})";
                rsp.set_header("Content-Type", "application/json");
                return;
            }

            // 保存图片文件
            if (!FileUtil(image_path).SetContent(image.content))
            {
                rsp.status = 500;
                rsp.body = R"({"result":false, "reason":"图片文件存储失败"})";
                rsp.set_header("Content-Type", "application/json");
                return;
            }

            // 构建视频信息的 JSON 对象
            Json::Value video_json;
            video_json["name"] = video_name;
            video_json["info"] = video_info;
            video_json["video"] = VIDEO_ROOT + video_name + video.filename;
            video_json["image"] = IMAGE_ROOT + video_name + image.filename;

            // 将视频信息插入数据库
            if (!tb_video->Insert(video_json))
            {
                rsp.status = 500;
                rsp.body = R"({"result":false, "reason":"数据库新增数据失败"})";
                rsp.set_header("Content-Type", "application/json");
                return;
            }

            // 插入成功，重定向到首页
            rsp.set_redirect("/index.html", 303);
        }

        // 删除视频信息的处理函数
        static void Delete(const httplib::Request &req, httplib::Response &rsp)
        {
            try
            {
                // 从请求中提取要删除的视频 ID
                int video_id = std::stoi(req.matches[1]);

                // 从数据库中查询要删除的视频信息
                Json::Value video;
                if (!tb_video->SelectOne(video_id, &video))
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"不存在视频信息"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }

                // 构建视频和图片的存储路径
                const std::string video_path = WWWROOT + video["video"].asString();
                const std::string image_path = WWWROOT + video["image"].asString();

                // 删除视频和图片文件
                if (std::remove(video_path.c_str()) != 0)
                {
                    ERR_LOG("删除视频文件失败: %s", video_path.c_str());
                }
                if (std::remove(image_path.c_str()) != 0)
                {
                    ERR_LOG("删除图片文件失败: %s", image_path.c_str());
                }

                // 从数据库中删除该视频信息
                if (!tb_video->Delete(video_id))
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"删除数据库信息失败"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }

                rsp.status = 200;
            }
            catch (const std::invalid_argument& e)
            {
                // 处理无效的视频 ID
                rsp.status = 400;
                rsp.body = R"({"result":false, "reason":"无效的视频 ID"})";
                rsp.set_header("Content-Type", "application/json");
            }
        }

        // 更新视频信息的处理函数
        static void Update(const httplib::Request &req, httplib::Response &rsp)
        {
            try
            {
                // 从请求中提取要修改的视频 ID
                int video_id = std::stoi(req.matches[1]);

                // 解析请求体中的新视频信息
                Json::Value video;
                if (!JsonUtil::UnSerialize(req.body, &video))
                {
                    rsp.status = 400;
                    rsp.body = R"({"result":false, "reason":"新的视频信息格式解析失败"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }

                // 更新数据库中的视频信息
                if (!tb_video->Update(video_id, video))
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"修改数据库信息失败"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }

                rsp.status = 200;
            }
            catch (const std::invalid_argument& e)
            {
                // 处理无效的视频 ID
                rsp.status = 400;
                rsp.body = R"({"result":false, "reason":"无效的视频 ID"})";
                rsp.set_header("Content-Type", "application/json");
            }
        }

        // 查询单个视频信息的处理函数
        static void SelectOne(const httplib::Request &req, httplib::Response &rsp)
        {
            try
            {
                // 从请求中提取要查询的视频 ID
                int video_id = std::stoi(req.matches[1]);

                // 从数据库中查询指定视频信息
                Json::Value video;
                if (!tb_video->SelectOne(video_id, &video))
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"查询数据库指定视频信息失败"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }

                // 将查询结果序列化为 JSON 字符串
                if (!JsonUtil::Serialize(video, &rsp.body))
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"序列化查询结果失败"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }

                rsp.set_header("Content-Type", "application/json");
            }
            catch (const std::invalid_argument& e)
            {
                // 处理无效的视频 ID
                rsp.status = 400;
                rsp.body = R"({"result":false, "reason":"无效的视频 ID"})";
                rsp.set_header("Content-Type", "application/json");
            }
        }

        // 查询所有视频信息的处理函数
        static void SelectAll(const httplib::Request &req, httplib::Response &rsp)
        {
            // 判断是否为模糊查询
            const bool select_flag = !req.has_param("search");
            const std::string search_key = req.has_param("search") ? req.get_param_value("search") : "";

            // 存储查询结果的 JSON 对象
            Json::Value videos;
            if (select_flag)
            {
                // 查询所有视频信息
                if (!tb_video->SelectAll(&videos))
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"查询数据库所有视频信息失败"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }
            }
            else
            {
                // 模糊查询视频信息
                if (!tb_video->SelectLike(search_key, &videos))
                {
                    rsp.status = 500;
                    rsp.body = R"({"result":false, "reason":"查询数据库匹配视频信息失败"})";
                    rsp.set_header("Content-Type", "application/json");
                    return;
                }
            }

            // 将查询结果序列化为 JSON 字符串
            if (!JsonUtil::Serialize(videos, &rsp.body))
            {
                rsp.status = 500;
                rsp.body = R"({"result":false, "reason":"序列化查询结果失败"})";
                rsp.set_header("Content-Type", "application/json");
                return;
            }

            rsp.set_header("Content-Type", "application/json");
        }

    public:
        // 构造函数，初始化服务器端口号
        Server(int port) : _port(port) {}

        // 启动服务器的方法
        bool RunModule()
        {
            // 初始化数据管理模块，创建指定的目录
            tb_video = std::unique_ptr<TableVideo>(new TableVideo());
            FileUtil(WWWROOT).CreateDirectory();
            const std::string video_real_path = WWWROOT + VIDEO_ROOT;
            FileUtil(video_real_path).CreateDirectory();
            const std::string image_real_path = WWWROOT + IMAGE_ROOT;
            FileUtil(image_real_path).CreateDirectory();

            // 搭建 HTTP 服务器，开始运行
            // 设置静态资源根目录
            _srv.set_mount_point("/", WWWROOT);

            // 添加请求 - 处理函数映射关系
            _srv.Post("/video", Insert);
            _srv.Delete("/video/(\\d+)", Delete);
            _srv.Put("/video/(\\d+)", Update);
            _srv.Get("/video/(\\d+)", SelectOne);
            _srv.Get("/video", SelectAll);

            // 启动服务器
            if (!_srv.listen("0.0.0.0", _port))
            {
                ERR_LOG("服务器启动失败，无法监听指定端口");
                return false;
            }
            return true;
        }
    };
}